<template>
  <img
    v-if="isVisible"
    :src="src"
    :alt="alt"
    :class="imgClass"
    @load="handleLoad"
    @error="handleError"
  >
  <div
    v-else
    :class="placeholderClass"
    :style="placeholderStyle"
  />
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'

const props = defineProps({
  src: { type: String, required: true },
  alt: { type: String, default: '' },
  imgClass: { type: String, default: '' },
  placeholderClass: { type: String, default: 'bg-gray-200 dark:bg-gray-700 animate-pulse' },
  width: { type: [String, Number], default: 'auto' },
  height: { type: [String, Number], default: 'auto' },
  threshold: { type: Number, default: 0.1 }, // Intersection Observer threshold
})

const isVisible = ref(false)
const imageLoaded = ref(false)
const hasError = ref(false)
let observer = null

const placeholderStyle = computed(() => ({
  width: typeof props.width === 'number' ? `${props.width}px` : props.width,
  height: typeof props.height === 'number' ? `${props.height}px` : props.height,
  display: isVisible.value ? 'none' : 'block', // Hide placeholder if image is visible
}))

const handleLoad = () => {
  imageLoaded.value = true
  hasError.value = false
}

const handleError = () => {
  hasError.value = true
  // 可以设置一个默认图片或者错误占位符
  // 例如: event.target.src = '/path/to/default-error-image.png'
}

onMounted(() => {
  if ('IntersectionObserver' in window) {
    observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            isVisible.value = true
            observer.disconnect()
          }
        })
      },
      { threshold: props.threshold }
    )
    observer.observe(document.querySelector(`[src="${props.src}"]`) || document.body) // Fallback to body if element not immediately found
  } else {
    // Fallback for browsers that do not support IntersectionObserver
    isVisible.value = true
  }
})

onUnmounted(() => {
  if (observer) {
    observer.disconnect()
  }
})
</script>

<style scoped>
/* 可以添加一些默认的图片样式 */
img {
  max-width: 100%;
  height: auto;
}
</style>
